<?php

namespace App\Http\Controllers\User;

use App\Events\OrderConfirm;
use App\Events\OrderCreated;
use App\Events\OrderDeleted;
use App\Events\OrderReceived;
use App\Events\OrderRestored;
use App\Exceptions\OperateFailedException;
use App\Exceptions\ParamValidateFailedException;
use App\Exceptions\ResourceNotFoundException;
use App\Exceptions\UnAuthorizedException;
use App\Http\Controllers\Controller;
use App\Http\Requests\OrderRequest;
use App\Jobs\OrderReceivedInfo;
use App\Models\Info;
use App\Models\Order;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class OrderController extends Controller
{
    public function __construct()
    {
         $this->middleware('auth:api')->except('destroy');
    }

    /* 创建订单
     *
     * @param request
     * @return \Illuminate\Http\JsonResponse
     * @throw OperateFailedException
     */
    public function create(OrderRequest $request)
    {
        $title = $request->get('title');
        $content = $request->get('content');
        $price = $request->get('price');
        $type = $request->get('kind');
        $phone = $request->get('phone');
        $ddl =  $request->get('ddl');
        DB::beginTransaction();
        try{
            $order = new Order();
            $order->title = $title;
            $order->content = $content;
            $order->price = $price;
            $order->type = $type;
            $order->phone = $phone;
            $order->deadline = $ddl;
            event(new OrderCreated($order));
            DB::commit();
       }catch (\Exception $exception){
            DB::rollBack();
            throw new OperateFailedException();
        }
        return $this->responseSuccess();
    }

    /* 订单关键词搜索
     *
     * @param search
     * @return App\Models\Order
     * @throw ResourceNotFoundException
     */
    public function search(Request $request)
    {
        /*Elasticsearch
         * $search = $request->get('search');
         * $orders = Order::search($search)->get();
         * return $orders;
         */

        //使用 Eloquent
        $search = $request->get('search');
        $orders = Order::where('title','like',"%{$search}%")
            ->orWhere('content','like',"%{$search}%")->get();
        return $orders;
    }

    /* 获取订单详情
     *
     * @param openid
     * @return \Illuminate\Http\JsonResponse
     * @throw ResourceNotFoundException
     */
    public function show($id)
    {
        $order = Order::where('id',$id)->with('providerUser')->with('receiverUser')->get();
        if (!$order){
            throw new ResourceNotFoundException();
        }
        return $this->responseSuccess($order);
    }

    /* 获取订单列表
     *
     * @param option | sort
     * @return \Illuminate\Http\JsonResponse
     * @throw OperateFailedException
     */
    public function list(Request $request,$option = Order::ORDER_TYPE_ALL, $sort = Order::ORDER_SORT_LATEST)
    {
        $search = $request->get('search');
        if (isset($search)){
            $orders = Order::where('title','like',"%{$search}%");
            //内容搜索
//                ->orWhere('content','like',"%{$search}%");
        }else{
            $orders = new Order();
        }

        $orders = Order::OrderType($orders,$option);
        $orders = Order::OrderSort($orders,$sort);
        $orders = Order::OrderStatus($orders,Order::ORDER_STATUS_PUBLISHED);
        $orders = $orders->paginate(5);
        Order::TypeToStr($orders);

        return response()->json($orders);
    }

    /* 获取个人订单列表
     *
     * @param status
     * @return \Illuminate\Http\JsonResponse
     * @throw OperateFailedException
     */
    public function myList($select = Order::MYORDER_ALL, $status = Order::ORDER_STATUS_ALL, $option = Order::ORDER_TYPE_ALL){
        $user = Auth::user();
        $openID = $user->openID;

        //校验用户身份
        try {
            $this->authorize('editOrder', $user);
        }catch (\Exception $exception) {
            throw new UnAuthorizedException();
        }

        //选择查看发布或接收订单
        switch ($select){
            case Order::MYORDER_ALL:
                $orders = Order::whereRaw('(provider = ? or receiver = ?)',[$openID,$openID]);
                break;
            case Order::MYORDER_PROVIDER:
                $orders = $user->orders();
                break;
            case Order::MYORDER_RECEIVER:
                $orders = $user->orders_receive();
                break;
            default:
                throw new ParamValidateFailedException();
        }
        //选择订单类型
        $orders = Order::OrderType($orders,$option);
        //选择订单状态
        $orders = Order::OrderStatus($orders,$status);
        //按最近时间查询
        $orders = Order::OrderSort($orders,Order::ORDER_SORT_LATEST);

        $orders = $orders->paginate(5);
//        Order::TypeToStr($orders);

        return response()->json($orders);
    }

    /* 接收订单
     *
     * @param order
     * @return \Illuminate\Http\JsonResponse
     * @throw OperateFailedException
     */
    public function receive(Order $order)
    {
        try {
            $provider = $order->providerUser;
            $this->authorize('selfDone', $provider);
        }catch (\Exception $exception) {
            throw new UnAuthorizedException();
        }

        DB::beginTransaction();
        try {
            event(new OrderReceived($order));
            OrderReceivedInfo::dispatch($order);
            DB::commit();
        }catch (\Exception $exception){
            DB::rollBack();
            throw new OperateFailedException();
        }
        return $this->responseSuccess();
    }

    /* 取消订单
     *
     * @param order
     * @return \Illuminate\Http\JsonResponse
     * @throw OperateFailedException
     */
    public function delete(Order $order)
    {
        $provider = $order->providerUser;
        $this->authorize('editOrder',$provider);
        DB::beginTransaction();
        try{
            $order->delete();
            event(new OrderDeleted($order));
            DB::commit();
        }catch (\Exception $exception){
            DB::rollBack();
            Log::error($exception->getMessage());
            throw new OperateFailedException();
        }
        return $this->responseSuccess();
    }

    /* 恢复订单
     *
     * @param id
     * @return response 200 or 500
     */
    public function restore($id)
    {
        $order = Order::withTrashed()->where('id',$id)->first();
        $provider = $order->providerUser;
        $this->authorize('editOrder',$provider);
        DB::beginTransaction();
        try{
            $order->restore();
            event(new OrderRestored($order));
            DB::commit();
        }catch (\Exception $exception){
            DB::rollBack();
            Log::error($exception->getMessage());
            throw new OperateFailedException();
        }
        return $this->responseSuccess();
    }

    /* 删除订单
     *
     * @param id
     * @return \Illuminate\Http\JsonResponse
     * @throw OperateFailedException
     */
    public function destroy($id)
    {
        $order = Order::withTrashed()->where('id',$id)->first();
        $provider = $order->providerUser;
        $auth = Auth::guard('web')->user();
        $auth ?: $this->authorize('editOrder',$provider);
        try{
            $order->forceDelete();
        }catch (\Exception $exception){
            Log::error($exception->getMessage());
            throw new OperateFailedException();
        }
        return $this->responseSuccess();
    }

    /* 订单重新编辑
     * 只能在取消后进行编辑操作
     *
     * @param id
     * @return \Illuminate\Http\JsonResponse
     * @throw OperateFailedException
     */
    public function edit(OrderRequest $request,$id)
    {
        $title = $request->get('title');
        $content = $request->get('content');
        $price = $request->get('price');
        $type = $request->get('kind');
        $ddl = $request->get('ddl');

        $order = Order::where('id',$id)->first();
        if ($order){
            $provider = $order->providerUser;
            $this->authorize('editOrder',$provider);
            DB::beginTransaction();
            try{
                $order->title = $title;
                $order->content = $content;
                $order->price = $price;
                $order->type = $type;
                $order->deadline = $ddl;
                event(new OrderCreated($order));
                DB::commit();
            }catch (\Exception $exception){
                DB::rollBack();
                throw new OperateFailedException();
            }
        }else{
            return $this->responseOperateFailed();
        }
        return $this->responseSuccess();
    }

    /* 订单确认完成
     *
     * @param id
     * @return \Illuminate\Http\JsonResponse
     * @throw OperateFailedException
     */
    public function confirm($order)
    {
        $user = Auth::user();
        try {
            $this->authorize('editOrder', $user);
        }catch (\Exception $exception) {
            throw new UnAuthorizedException();
        }
        $order = Order::where('id',$order)->first();
        return event(new OrderConfirm($order)) ? $this->responseSuccess() : $this->responseOperateFailed();
    }
}
